package com.eastfair.venueservice.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
//import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eastfair.boot.request.PageParams;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.venuebooking.vo.ExhibitionSpaceVO;
import com.eastfair.venueservice.dao.ExhibitionDrawingMapper;
import com.eastfair.venueservice.dto.ExhibitionDrawingDTO;
import com.eastfair.venueservice.dto.ExhibitionManageQuery;
import com.eastfair.venueservice.entity.ExhibitionDrawing;
import com.eastfair.venueservice.service.ExhibitionDrawingService;
import com.eastfair.venueservice.service.ExhibitionManageService;
import com.eastfair.venueservice.service.VenueManageExhibitionSpaceService;
import com.eastfair.venueservice.vo.ExhibitionDrawingVO;
import com.eastfair.venueservice.vo.ExhibitionManageVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 业务实现类
 * 综合展会图纸分类
 * </p>
 *
 * @author dq
 * @date 2022-10-27
 */
@Slf4j
@Service
//@DS("#thread.tenant")
public class ExhibitionDrawingServiceImpl extends SuperServiceImpl<ExhibitionDrawingMapper, ExhibitionDrawing> implements ExhibitionDrawingService {

    @Resource
    private VenueManageExhibitionSpaceService venueManageExhibitionSpaceService;

    @Resource
    private ExhibitionManageService exhibitionManageService;

    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<ExhibitionDrawing> modelList) {
        modelList.forEach(s -> s.setIsDeleted(BusinessConstant.YES));
        return R.successDef();
    }

    @Override
    protected R<Boolean> handlerSave(ExhibitionDrawing model) {
        model.setProjectId(ContextUtil.getProjectId());
        model.setSubsystemId(ContextUtil.getSubSystemId());
        return R.successDef();
    }

    @Override
    public List<ExhibitionDrawing> listExhibitionByDrawingId(ExhibitionDrawingDTO query) {
        QueryWrapper<ExhibitionDrawing> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .eq(ExhibitionDrawing::getIsDeleted, BusinessConstant.DELETE_NO)
                .eq(query.getExhibitionId() != null, ExhibitionDrawing::getExhibitionId, query.getExhibitionId())
                .eq(StrUtil.isNotBlank(query.getSpaceCode()), ExhibitionDrawing::getSpaceCode, query.getSpaceCode())
                .eq(query.getDrawingId() != null, ExhibitionDrawing::getDrawingId, query.getDrawingId())
        ;
        return list(queryWrapper);
    }

    @Override
    public Page<ExhibitionDrawingVO> listExhibitionByDrawingId(PageParams<ExhibitionDrawingDTO> pageParams) {
        log.info("listExhibitionDrawing - 分页查询展会图纸分类关系列表, pageParams={}", pageParams);
        // 分页查询展会图纸分类列表
        QueryWrapper<ExhibitionDrawing> queryWrapper = createExhibitionQueryWrapper(pageParams.getModel());
        Page<ExhibitionDrawing> page = page(pageParams.buildPage(), queryWrapper);
        Page<ExhibitionDrawingVO> voPage = new Page<>();
        BeanUtil.copyProperties(page, voPage);
        List<ExhibitionDrawing> list = page.getRecords();
        if (list == null || list.isEmpty()) {
            return voPage;
        }
        // 查询展会列表
        List<Long> exhibitionIds = list
                .stream()
                .map(ExhibitionDrawing::getExhibitionId)
                .collect(Collectors.toList());
        Map<Long, String> exhibitionMap = getExhibitionMapByExhibitionIds(exhibitionIds);
        // 封装展会名称
        List<ExhibitionDrawingVO> voList = list
                .stream()
                .map(exhibitionDrawing -> {
                    ExhibitionDrawingVO exhibitionDrawingVO = BeanUtil.toBean(exhibitionDrawing, ExhibitionDrawingVO.class);
                    String exhibitionName = exhibitionMap.get(exhibitionDrawing.getExhibitionId());
                    exhibitionDrawingVO.setExhibitionName(exhibitionName);
                    return exhibitionDrawingVO;
                })
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        return voPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveExhibitionDrawing(ExhibitionDrawingDTO exhibitionDrawingDTO) {
        log.info("saveExhibitionDrawing - 保存展会图纸, exhibitionDrawingDTO={}", exhibitionDrawingDTO);
        ExhibitionDrawing exhibitionDrawing = BeanUtil.toBean(exhibitionDrawingDTO, ExhibitionDrawing.class);
        return save(exhibitionDrawing);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveBatch(List<ExhibitionDrawingDTO> list) {
        if (list == null || list.isEmpty()) {
            return true;
        }
        // 批量保存图纸
        list.forEach(this::saveExhibitionDrawing);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveBatch(List<ExhibitionDrawingDTO> paramList, Boolean enableAllSpace) {
        if (paramList == null || paramList.isEmpty()) {
            return true;
        }
        ExhibitionDrawingDTO firstParam = paramList.get(0);
        Long exhibitionId = firstParam.getExhibitionId();
        String spaceCode = firstParam.getSpaceCode();
        if (enableAllSpace != null && enableAllSpace) {
            // 应用于全部展厅
            // 删除展会下的图纸
            removeByExhibitionId(exhibitionId);
            // 查询展会的全部展厅
            List<ExhibitionSpaceVO> exhibitionSpaceList = venueManageExhibitionSpaceService.listByExhibitionManageId(exhibitionId);
            if (exhibitionSpaceList == null || exhibitionSpaceList.isEmpty()) {
                return true;
            }
            // 封装展会下全部展厅图纸的参数
            List<ExhibitionDrawingDTO> list = new ArrayList<>(16);
            for (ExhibitionSpaceVO exhibitionSpaceVO : exhibitionSpaceList) {
                for (ExhibitionDrawingDTO exhibitionDrawingDTO : paramList) {
                    ExhibitionDrawingDTO paramExhibitionDrawingDTO = BeanUtil.toBean(exhibitionDrawingDTO, ExhibitionDrawingDTO.class);
                    paramExhibitionDrawingDTO.setSpaceCode(exhibitionSpaceVO.getSpaceCode());
                    list.add(paramExhibitionDrawingDTO);
                }
            }
            return saveBatch(list);
        }
        // 只应用于当前展厅
        // 删除展会展厅下设置的图纸
        removeByExhibitionIdAndSpaceCode(exhibitionId, spaceCode);
        return saveBatch(paramList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeByExhibitionId(Long exhibitionId) {
        // 查询当前展会设置的图纸
        ExhibitionDrawingDTO param = new ExhibitionDrawingDTO();
        param.setExhibitionId(exhibitionId);
        List<ExhibitionDrawing> list = listExhibitionByDrawingId(param);
        if (list == null || list.isEmpty()) {
            return true;
        }
        // 删除主场在该展会下设置的图纸
        List<Long> ids = list
                .stream()
                .map(ExhibitionDrawing::getId)
                .collect(Collectors.toList());
        return removeByIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeByExhibitionIdAndSpaceCode(Long exhibitionId, String spaceCode) {
        // 查询当前展会的展厅设置的图纸
        ExhibitionDrawingDTO param = new ExhibitionDrawingDTO();
        param.setExhibitionId(exhibitionId);
        param.setSpaceCode(spaceCode);
        List<ExhibitionDrawing> list = listExhibitionByDrawingId(param);
        if (list == null || list.isEmpty()) {
            return true;
        }
        // 删除主场在该展会下设置的图纸
        List<Long> ids = list
                .stream()
                .map(ExhibitionDrawing::getId)
                .collect(Collectors.toList());
        return removeByIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeByDrawingId(Long drawingId) {
        log.info("removeById - 删除, id={}", drawingId);
        // 图纸ID查询展会图纸
        ExhibitionDrawingDTO param = new ExhibitionDrawingDTO();
        param.setDrawingId(drawingId);
        List<ExhibitionDrawing> list = listExhibitionByDrawingId(param);
        // 根据图纸ID删除展会图纸
        List<Long> ids = list
                .stream()
                .map(ExhibitionDrawing::getId)
                .collect(Collectors.toList());
        return removeByIds(ids);
    }

    private QueryWrapper<ExhibitionDrawing> createExhibitionQueryWrapper(ExhibitionDrawingDTO query) {
        QueryWrapper<ExhibitionDrawing> queryWrapper = new QueryWrapper<ExhibitionDrawing>()
                .select("distinct exhibition_id");
        queryWrapper
                .lambda()
                .eq(ExhibitionDrawing::getIsDeleted, BusinessConstant.DELETE_NO)
                .eq(query.getDrawingId() != null, ExhibitionDrawing::getDrawingId, query.getDrawingId());
        return queryWrapper;
    }

    private Map<Long,String> getExhibitionMapByExhibitionIds(List<Long> exhibitionIds) {
        // 查询展会列表
        ExhibitionManageQuery exhibitionManageQuery = new ExhibitionManageQuery();
        exhibitionManageQuery.setIds(exhibitionIds);
        R<List<ExhibitionManageVO>> result = exhibitionManageService.queryAllExhibitionManage(exhibitionManageQuery);
        List<ExhibitionManageVO> exhibitionManageList = result.getData();
        if (exhibitionManageList == null || exhibitionManageList.isEmpty()) {
            return Collections.emptyMap();
        }
        // 封装展会名称
        Map<Long, String> exhibitionMap = new HashMap<>(16);
        exhibitionManageList.forEach(exhibitionManageVO -> exhibitionMap.put(exhibitionManageVO.getId(), exhibitionManageVO.getExhibitionName()));
        return exhibitionMap;
    }
}
